import Stack from "generator/utils/stack";
import Layer from 'generator/index/Layout/WorkBench/Layer/index.vue'
import Inertia from 'generator/index/Layout/WorkBench/Inertia/index.vue'
import EditorExplain from 'generator/index/Layout/WorkBench/Explain/index.vue'
import Preview from 'generator/preview/index.vue'
import EditModel from 'generator/edit/index.vue'
import { nextTick, onMounted, onUnmounted, ref } from "vue";
import type { Ref } from 'vue'
import html2canvas from "html2canvas";
import { download } from "wft-utils";
import Bus from '@/utils/bus'
export function usePanelToobar(panelJson: Ref<TPanel>) {
  const showLayer = ref(false)
  const showInertia = ref(false)
  const showPreview = ref(false)
  const PanelLayerRef = ref<InstanceType<typeof Layer>>()
  const InertiaRef = ref<InstanceType<typeof Inertia>>()
  const EditorExplainRef = ref<InstanceType<typeof EditorExplain>>()
  const stack = ref(new Stack())
  const PreviewRef = ref<InstanceType<typeof Preview>>()
  const EditModelRef = ref<InstanceType<typeof EditModel>>()
  const showEditModel = ref(false)

  onMounted(() => {
    Bus.on('on-page-change', clearStack)
    initStack()
    Bus.on('addStack', addStack)
  })

  onUnmounted(() => {
    Bus.off('addStack', addStack)
  })

  function initStack() {
    addStack()
  }

  function clearStack() {
    stack.value.clear()
    setTimeout(() => {
      initStack()
    }, 500)
  }

  // 页面预览
  function startPreview() {
    showPreview.value = true
    nextTick(() => {
      PreviewRef.value?.init()
    })
  }

  // 关闭预览
  function closePreview() {
    PreviewRef.value?.close()
    setTimeout(() => {
      showPreview.value = false
    }, 1000)
  }

  // 切换图层显示
  function toggleLayer () {
    if(!showLayer.value) {
      PanelLayerRef.value!.initPosition()
    }
    showLayer.value = !showLayer.value
    if(showLayer.value) {
      PanelLayerRef.value!.initEvent()
    } else {
      PanelLayerRef.value!.clearEvent()
    }
  }

  // 切换惰性控件面板显示
  function toggleInertia () {
    if(!showInertia.value) {
      InertiaRef.value!.initPosition()
    }
    showInertia.value = !showInertia.value
    if(showInertia.value) {
      InertiaRef.value!.initEvent()
    } else {
      InertiaRef.value!.clearEvent()
    }
  }

  // 打开惰性控件面板
  function openInertia () {
    if(showInertia.value) return
    InertiaRef.value!.initPosition()
    showInertia.value = true
    InertiaRef.value!.initEvent()
  }

  // 撤销
  function undo() {
    const data = stack.value.undo()
    if(data) panelJson.value = JSON.parse(data)
  }
  // 恢复
  function redo() {
    const data = stack.value.redo()
    if(data) panelJson.value = JSON.parse(data)
  }

  // 添加操作记录
  function addStack() {
    stack.value.push(JSON.stringify(panelJson.value))
  }

  // 删除组件
  function deleteComp() {
    let comps = panelJson.value.children
    outer: for(let i = 0; i < comps.length; i++) {
      if(comps[i].type == 'inertia') continue
      if(comps[i].config.isActive && comps[i].type != 'advanced') {
        comps.splice(i, 1)
        addStack()
        break outer;
      }
      if(comps[i].type == 'advanced') {
        for(let j = 0; j < comps[i].children!.length; j++) {
          if(comps[i].children![j].config.isActive) {
            comps[i].children!.splice(j, 1)
            addStack()
            break outer;
          }
        }
        if(comps[i].config.isActive) {
          comps.splice(i, 1)
          addStack()
          break outer;
        }
      }
    }
  }

  // 关闭图层
  function closeLayer () {
    showLayer.value = false
    PanelLayerRef.value!.clearEvent()
  }

  // 关闭惰性控件面板
  function closeInertia () {
    showInertia.value = false
    InertiaRef.value!.clearEvent()
  }

  // 生成海报
  function exportPoster() {
    html2canvas(document.getElementById('wft-mobile-container-panel')!).then((canvas: HTMLCanvasElement) => {
      canvas.toBlob(blob => {
        download((blob as Blob), `${panelJson.value.name}.png`)
      }, "image/png")
    })
  }

  // 说明
  function editorExplain() {
    EditorExplainRef.value!.init()
  }

  // 导出JSON
  function exportJson() {
    const json = JSON.stringify(panelJson.value)
    const link = document.createElement('a')
    const URL = window.URL || window.webkitURL;
    link.href = URL.createObjectURL(new Blob([json]))
    link.download = `${panelJson.value.name}.json`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
  }

  // 在线编辑
  function edit() {
    EditModelRef.value?.init(panelJson.value)
    showEditModel.value = true
  }

  // 关闭在线编辑
  function closeEditModel() {
    EditModelRef.value?.close()
    setTimeout(() => {
      showEditModel.value = false
    }, 1000)
  }

  // 更新面板数据
  function updatePanelJson(editJson: TPanel) {
    panelJson.value = editJson
    closeEditModel()
  }

  return { 
    stack,
    showLayer,
    showInertia,
    showPreview,
    PanelLayerRef,
    InertiaRef,
    EditorExplainRef,
    PreviewRef,
    EditModelRef,
    showEditModel,
    toggleLayer,
    toggleInertia,
    openInertia,
    undo,
    redo,
    addStack,
    startPreview,
    closePreview,
    deleteComp,
    closeLayer,
    closeInertia,
    exportPoster,
    editorExplain,
    exportJson,
    edit,
    closeEditModel,
    updatePanelJson
  }
}
